package com.xbongbong.paas.script.controller;

import com.alibaba.fastjson.JSON;
import com.xbongbong.paas.domain.entity.PaasFormEntity;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.model.PaasFormExplainModel;
import com.xbongbong.paas.model.PaasFormModel;
import com.xbongbong.paas.script.pojo.EffectApiBusinessPojo;
import com.xbongbong.paas.script.pojo.EffectApiCompanyPojo;
import com.xbongbong.paas.script.pojo.EffectApiFieldPojo;
import com.xbongbong.paas.script.pojo.EffectApiFormPojo;
import com.xbongbong.paas.script.pojo.dto.EffectApiCompanyDTO;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.pro.config.ProBaseConfig;
import com.xbongbong.pro.constant.XbbProConstant;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.sys.domain.entity.CompanyEntity;
import com.xbongbong.sys.model.ApiTokenModel;
import com.xbongbong.sys.model.CompanyModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

/**
 * @author 吴峰
 * @version v1.0
 * @date 2020/5/8 11:09
 * @since v1.0
 */
@RestController
@RequestMapping(XbbProConstant.API_ROOT_PREFIX+"/script/subForm")
public class ApiSubFormScriptController {
    private static final Logger LOG = LoggerFactory.getLogger(ApiSubFormScriptController.class);
    @Resource
    private ProBaseConfig proBaseConfig;
    @Resource
    private ApiTokenModel apiTokenModel;
    @Resource
    private CompanyModel companyModel;
    @Resource
    private PaasFormExplainModel paasFormExplainModel;
    @Resource
    private PaasFormModel paasFormModel;

    @RequestMapping(value = "/effectApiCompany", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String effectApiCompany(@RequestBody @Valid EffectApiCompanyDTO effectApiCompanyDTO, BindingResult br) throws XbbException {
        if (!proBaseConfig.getXbbCode().equals(effectApiCompanyDTO.getXbbCode())) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006);
        }

        //十天内有正常请求API的公司
        Long endTimeStart = DateTimeUtil.getTodayInt() - (86400 * 10);
        List<String> corpidIn = apiTokenModel.getCorpidIn(endTimeStart);
        Map<String, CompanyEntity> companyMap = getCompanyMap(corpidIn);

        Integer allSize = corpidIn.size();
        Integer nowSize = 0;
        List<EffectApiCompanyPojo> effectApiCompanys = new ArrayList<>();
        //表单解释查询有些慢，公司数在50多
        for (String corpid : corpidIn) {
            nowSize++;
            LOG.warn("----------------------------" + nowSize + "/" + allSize);
            EffectApiCompanyPojo effectApiCompany = new EffectApiCompanyPojo();
            CompanyEntity company = companyMap.get(corpid);
            if (Objects.isNull(company)) {
                effectApiCompany.setCorpid(corpid);
                effectApiCompany.setCorpName("----公司不存在----");
                effectApiCompanys.add(effectApiCompany);
                continue;
            }
            effectApiCompany.setCorpid(corpid);
            effectApiCompany.setCorpName(company.getCorpName());

            Map<String, Object> param = new HashMap<>();
            param.put("corpid", corpid);
            param.put("linkFieldType", FieldTypeEnum.SUB_FORM.getType());
            param.put("del", 0);

            List<PaasFormExplainEntity> paasFormExplainList = paasFormExplainModel.findEntitys(param);

            Map<Long, String> formMap = getFormNameMap(corpid, paasFormExplainList);

            //业务类型：解释
            Map<Integer, List<PaasFormExplainEntity>> paasFormExplainMap = new HashMap<>();
            for (PaasFormExplainEntity paasFormExplain : paasFormExplainList) {
                Integer businessType = paasFormExplain.getBusinessType();
                List<PaasFormExplainEntity> paasFormExplains = null;
                if (paasFormExplainMap.containsKey(businessType)) {
                    paasFormExplains = paasFormExplainMap.get(businessType);
                } else {
                    paasFormExplains = new ArrayList<>();
                }
                paasFormExplains.add(paasFormExplain);
                paasFormExplainMap.put(businessType, paasFormExplains);
            }

            List<EffectApiBusinessPojo> businessTypes = new ArrayList<>();

            Set<Integer> businessTypeSet = paasFormExplainMap.keySet();
            for (Integer businessType : businessTypeSet) {
                EffectApiBusinessPojo effectApiBusinessPojo = new EffectApiBusinessPojo();
                XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByCode(businessType);
                effectApiBusinessPojo.setBusinessType(businessType);
                effectApiBusinessPojo.setBusinessName(xbbRefTypeEnum.getName());
                List<EffectApiFormPojo> formList = new ArrayList<>();
                List<PaasFormExplainEntity> paasFormExplains = paasFormExplainMap.get(businessType);
                if (Objects.isNull(paasFormExplains) || paasFormExplains.isEmpty()) {
                    continue;
                }

                for (PaasFormExplainEntity paasFormExplain : paasFormExplains) {
                    Long formId = paasFormExplain.getFormId();
                    String formName = formMap.get(formId);
                    EffectApiFormPojo effectApiFormPojo = new EffectApiFormPojo();
                    effectApiFormPojo.setFormId(formId);
                    effectApiFormPojo.setFormName(formName);
                    List<EffectApiFieldPojo> fields = getSubFormFields(paasFormExplain);
                    effectApiFormPojo.setFields(fields);
                    formList.add(effectApiFormPojo);
                }
                effectApiBusinessPojo.setFormList(formList);
                businessTypes.add(effectApiBusinessPojo);
            }
            effectApiCompany.setBusinessTypes(businessTypes);
            effectApiCompanys.add(effectApiCompany);
        }
        LOG.warn("------------完成----------------");
        for (EffectApiCompanyPojo effectApiCompany : effectApiCompanys) {
            LOG.warn("corpid:" + effectApiCompany.getCorpid() + " 公司名:" + effectApiCompany.getCorpName());
            List<EffectApiBusinessPojo> businessTypes = effectApiCompany.getBusinessTypes();
            if (Objects.isNull(businessTypes) || businessTypes.isEmpty()) {
                continue;
            }
            for (EffectApiBusinessPojo businessTypePojo : businessTypes) {
                LOG.warn("--businessType:" + businessTypePojo.getBusinessType() + " 业务类型名:" + businessTypePojo.getBusinessName());
                List<EffectApiFormPojo> formList = businessTypePojo.getFormList();
                for (EffectApiFormPojo effectApiFormPojo : formList) {
                    LOG.warn("----formId:" + effectApiFormPojo.getFormId() + " 表单名:" + effectApiFormPojo.getFormName());
                    List<EffectApiFieldPojo> fields = effectApiFormPojo.getFields();
                    for (EffectApiFieldPojo field : fields) {
                        LOG.warn("------attr:" + field.getAttr() + " attrName:" + field.getAttrName());
                    }

                }
            }
        }
        return "";
    }

    private List<EffectApiFieldPojo> getSubFormFields(PaasFormExplainEntity paasFormExplain) {
        List<EffectApiFieldPojo> subFormFields = new ArrayList<>();
        if (Objects.isNull(paasFormExplain)) {
            return subFormFields;
        }

        List<FieldAttrEntity> explainList = JSON.parseArray(paasFormExplain.getExplains(), FieldAttrEntity.class);
        Iterator<FieldAttrEntity> iterator = explainList.iterator();
        while (iterator.hasNext()) {
            FieldAttrEntity fieldAttrEntity = iterator.next();
            FieldTypeEnum fieldTypeEnum = FieldTypeEnum.getFieldTypeEnum(fieldAttrEntity.getFieldType());

            if (Objects.equals(fieldTypeEnum, FieldTypeEnum.SUB_FORM)) {
                EffectApiFieldPojo effectApiFieldPojo = new EffectApiFieldPojo();
                effectApiFieldPojo.setAttr(fieldAttrEntity.getAttr());
                effectApiFieldPojo.setAttrName(fieldAttrEntity.getAttrName());
                subFormFields.add(effectApiFieldPojo);
            }
        }
        return subFormFields;
    }

    private Map<Long, String> getFormNameMap(String corpid, List<PaasFormExplainEntity> paasFormExplainList) {
        Map<Long, String> formNameMap = new HashMap<>();
        List<Long> formIdIn = new ArrayList<>();
        for (PaasFormExplainEntity paasFormExplain : paasFormExplainList) {
            formIdIn.add(paasFormExplain.getFormId());
        }
        Map<String, Object> param = new HashMap<>();
        param.put("formIdIn", formIdIn);
        param.put("corpid", corpid);
        param.put("del", 0);
        List<PaasFormEntity> paasForms = paasFormModel.findEntity(param);
        for (PaasFormEntity paasForm : paasForms) {
            formNameMap.put(paasForm.getId(), paasForm.getName());
        }
        return formNameMap;
    }

    /**
     * 获取公司map
     * @param corpidIn
     * @return
     */
    private Map<String, CompanyEntity> getCompanyMap(List<String> corpidIn) {
        Map<String, CompanyEntity> companyMap = new HashMap<>();
        Map<String, Object> param = new HashMap<>();
        param.put("corpidIn", corpidIn);
        param.put("del", 0);
        List<CompanyEntity> companys = companyModel.findEntitys(param);
        for (CompanyEntity company : companys) {
            companyMap.put(company.getCorpid(), company);
        }
        return companyMap;
    }

}
